import {
  defineComponent,
  provide,
  toRaw,
  PropType
} from "vue";
import {Rules} from "async-validator";
import {useExpose} from '../../uses/expose';
import {FormContext, FormItemContext, FormKey} from "./types";
import './index.scss';

export default defineComponent({
  name: 'Form',
  props: {
    model: Object,
    rules: Object as PropType<Rules>
  },
  emits: ['submit', 'fail'],
  setup(props, { slots, emit }) {
    const formItems: FormItemContext[] = [];
    const addItem = (item: FormItemContext): void => {
      formItems.push(item);
      // console.log('add formItems', formItems);
    }
    const removeItem = (id: string): void => {
      if (formItems.length) {
        const index = formItems.findIndex(item => item.id === id);
        if (index > -1) {
          formItems.splice(index, 1);
        }
      }
    }

    const FormInstance: FormContext = {
      model: props.model!,
      rules: props.rules!,
      addItem,
      removeItem
    }
    provide(FormKey, FormInstance);

    const validate = (callback?: (valid: boolean) => void): Promise<any> => {
      return Promise.all(formItems.filter(child => child.prop).map(child => child.validate())).then(() => {
        if (callback) {
          callback(true);
        }
          emit('submit', toRaw(props.model)); // toRaw返回原始对象
        return Promise.resolve(true);
      }).catch(errors => {
        if (callback) {
          callback(errors);
        }
        emit('fail', errors);
        return Promise.reject(errors)
      });
    }
    useExpose({ validate });
    const handleSubmit = (event: Event): void => {
      event.preventDefault();
      validate();
    }
    return () => {
      return (
        <form class="ant-form" onSubmit={ handleSubmit }>
          { slots.default!() }
        </form>
      );
    }
  }
});
